# -*- coding: utf-8 -*-
"""
Created on Sat Dec 21 19:34:46 2024

@author: lenovo
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
import matplotlib.dates as mdates
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter
import cartopy.feature as cfeature
import shapely.geometry as sgeom
from datetime import datetime

path=r'D:\Work_log\2025.1.22zgb_dusurui\trmatch_cntl_tr0016_mean'

class tydat:
    def __init__(self,path):
        self.df=pd.read_csv(path,skiprows=5,engine='python',sep=' & |\s',header=None) 
        self.colors=['#000000','#00ffff','#0000ff', '#FF8C00','#FF0000','#FF00FF']
        self.fig,self.ax= plt.subplots(subplot_kw={'projection': ccrs.PlateCarree()},figsize=(10, 10),dpi=300)
        for i in range(len(self.df)):
            self.df.iloc[i,14]=self.tyclass(self.df.iloc[i,13])
        lon= self.df[1]
        self.lon=np.where(lon>180,lon-360,lon)
        self.lat= self.df[2].values
        self.tp = self.df[14]
        self.umax = self.df[13]
        self.pmin = self.df[10]
        # 这里需要转成datetime对象
        self.time = [datetime.strptime(str(t),'%Y%m%d%H') for t in self.df[0] ]
        
        
    def tyclass(self,v): 
        if v<=17.2:
            return '热带低压'
        elif v<=24.5:
            return '热带风暴'
        elif v<=32.7:
            return '强热带风暴'
        elif v<=41.5:
            return '台风'
        elif v<=51.0:
            return '强台风'
        else :
            return '超强台风'
        
    def get_color(self,level):
        if level == '热带低压' or level == '热带扰动':
            color=self.colors[0]
        elif level == '热带风暴':
            color=self.colors[1]
        elif level == '强热带风暴':
            color=self.colors[2]
        elif level == '台风':
            color=self.colors[3]
        elif level == '强台风':
            color=self.colors[4]
        elif level == '超强台风':
            color=self.colors[5]
        return color
    
    def basemap(self,extent,title):
        self.ax.add_feature(cfeature.COASTLINE,linewidth=0.6) #海岸线
        self.ax.add_feature(cfeature.BORDERS,linewidth=0.5)   #国界
        china_provinces = cfeature.NaturalEarthFeature(category='cultural',name='admin_1_states_provinces_lines', scale='10m', facecolor='none')
        self.ax.add_feature(china_provinces, edgecolor='black', linewidth=0.3) #省界
        self.ax.set(xlim=(extent[0],extent[1]))
        self.ax.set(ylim=(extent[2],extent[3]))    
        #这种设定方法适用于这样子给出范围。
        self.ax.set_xticks(np.arange(extent[0], extent[1]+5, 10))
        self.ax.set_yticks(np.arange(extent[2], extent[3]+5, 5))
        self.ax.xaxis.set_major_formatter(LongitudeFormatter())
        self.ax.xaxis.set_minor_locator(plt.MultipleLocator(1))
        self.ax.yaxis.set_major_formatter(LatitudeFormatter())
        self.ax.yaxis.set_minor_locator(plt.MultipleLocator(1))
        self.ax.tick_params(axis='both', labelsize=10, direction='out')
        self.ax.set_title(title)
                 
    def track(self,sep=1):
        a = mlines.Line2D([],[],color=self.colors[0],marker='o',markersize=7, label='TD',ls='')
        b = mlines.Line2D([],[],color=self.colors[1], marker='o',markersize=7, label='TS',ls='')
        c = mlines.Line2D([],[],color=self.colors[2], marker='o',markersize=7, label='STS',ls='')
        d = mlines.Line2D([],[],color=self.colors[3], marker='o',markersize=7, label='TY',ls='')
        e = mlines.Line2D([],[],color=self.colors[4], marker='o',markersize=7, label='STY',ls='')
        f = mlines.Line2D([],[],color=self.colors[5], marker='o',markersize=7, label='SSTY',ls='')
        self.ax.legend(handles=[a,b,c,d,e,f], numpoints=1, handletextpad=0, loc='upper left', shadow=True)
        lon= self.lon
        lat= self.lat
        tp = self.tp
        # 按12小时一次画
        ll=np.arange(0,len(self.df),sep) 
        ll2=np.arange(0,len(self.df)-1,1)
        # 画点
        for i in ll:
            self.ax.scatter(lon[i], lat[i], marker='o', s=10, color=self.get_color(tp[i]))
        # 连线
        for i in ll2:
            pointA = lon[i],lat[i]
            pointB = lon[i+1],lat[i+1]
            self.ax.add_geometries([sgeom.LineString([pointA, pointB])], color=self.get_color(tp[i+1]),crs=ccrs.PlateCarree())
    

    def trackplot(self,extent,title,sep=1):
        self.fig,self.ax= plt.subplots(subplot_kw={'projection': ccrs.PlateCarree()},figsize=(10, 4),dpi=300)
        self.basemap(extent,title)
        self.track(sep)
        plt.savefig(f".\\track{title}.png", dpi=400)
        
    def SLP_WIND(self,title):
        max_wind_label = np.arange(0,70,10)  # 最大风速 (m/s)
        min_slp_label = np.arange(920,1030,10)
        fig, ax1 = plt.subplots(figsize=(10, 4))

        # 绘制最大风速
        ax1.plot(self.time, self.umax, 'o-', color='red', label='Max-Wind')
        ax1.set_xlabel('Time (month-day)')
        ax1.set_ylabel('max wind (m/s)', color='red')
        ax1.set_yticks( max_wind_label )
        ax1.tick_params(axis='y', labelcolor='red')
        ax1.set_title(title)
        ax1.xaxis.set_major_locator(mdates.DayLocator(interval=3))  # 每5天一个主刻度
        ax1.xaxis.set_minor_locator(mdates.DayLocator(interval=1))  # 每1天一个次刻度
        ax1.xaxis.set_major_formatter(mdates.DateFormatter("%m-%d"))  # 主刻度显示的格式

        # 创建共享x轴的第二个y轴
        ax2 = ax1.twinx()
        ax2.plot(self.time, self.pmin, 'o-', color='blue', label='Min-SLP')
        ax2.set_ylabel('min SLP (hPa)', color='blue')
        ax2.set_yticks( min_slp_label )
        ax2.tick_params(axis='y', labelcolor='blue')
        plt.savefig(f".\\VP{title}.png", dpi=400)



                
        
extent=[100,165,15,50]
title="DUSURUI"
sep=1  #隔二画一


t=tydat(path)
t.trackplot(extent, title,sep)
t.SLP_WIND(title)

    